import DatePicker from "components/antd-compatible/date-picker";
/**
 * Created by tanbingqin on 2020/7/6.
 */
import React, { Component, PropTypes } from "react";
import { messages, eventTrack } from 'share/common'
import { connect } from 'react-redux';
import moment from 'moment'
import requestService from 'containers/request/request.service'
import travelService from 'containers/request/travel-request/travel.service'
import baseService from 'share/base.service'
import errorMessage from 'share/errorMessage';
import 'styles/request/new-card-request.scss'
import 'styles/request/new-request/expense-type-modal.scss'
import { Button, Row, Col, Icon,  Checkbox, message, Popconfirm, Spin, Divider, Modal } from 'antd'
import Condition from 'components/condition';
const If = Condition.If;
import travelUtil from 'containers/request/travel-request/travelUtil'
import requestUtil from 'containers/request/slide/request-util'
import TravelLocation from 'containers/request/travel-request/comp/location'
const CheckboxGroup = Checkbox.Group;
import debounce from 'lodash.debounce'
import customField from 'share/customField'
import ItineraryForm from 'containers/request/slide/content/itinerary-form'
import SubsidyDetail from 'containers/request/slide/content/subsidy-detail'
import ExpenseTypeSelector from 'components/template/expense-type-selector'

class RequestItineraryBudget extends Component{
  constructor(props) {
    super(props);
    this.state = {
      loading: false,
      savingLoading: false,
      expenseForms: [], //费用表单
      expenseTypeList: [], //费用列表
      suppliers: {}, //机酒火消费商列表
      currencyOptions: [], //预算控件的币种列表
      apportionParams: {}, //分摊所需的相关参数
      itineraryHeadList: [], //行程头列表
      modalVisible: false,
      modalLoading: false,
      selectedExpense: {},
      expenseItinerary: {}, //标记在哪个行程下操作添加明细
      warnExchangeRateTol: null,//汇率容差警告值
      prohibitExchangeRateTol: null,//汇率容差禁止值
    };
    this.formRefObj = {}; //每个费用下有个表单实例，key为`${itineraryHeadId}|${quickExpenseOID}`
  }

  componentDidMount() {
    this.initHeadList();
    this.initExpenseForms();
    this.initSuppliers();
    this.initCurrencyOptions();
    this.initApportionParams(); //每次打开侧滑时初始化，所以不用在componentWillReceiveProps再次处理，每次拿到的单据控件都是最新的
    this.initRateDeviation();
  }

  componentWillReceiveProps(nextProps) {}

  //初始化行程头数据
  initHeadList = () => {
    let { itineraryHeadList, isBatchSubsidy } = this.props.params;
    itineraryHeadList && itineraryHeadList.forEach(itinerary => {
      itinerary.quickExpenseList = [];
      if (!isBatchSubsidy && itinerary.quickExpenseOIDList && itinerary.quickExpenseOIDList.length) {
        itinerary.quickExpenseOIDList.forEach(quickExpenseOID => {
          //批量添加的行程头下快捷计划费用是不会有重复，但是打开侧滑后，用户自己添加费用类型可以存在一个行程头下费用类型重复的情况，所以新建用frontOID做为key
          itinerary.quickExpenseList.push({
            expenseTypeOID: quickExpenseOID,
            frontOID: travelUtil.generateUid()
          });
        });
      }
    });
    this.setState({itineraryHeadList});
  };

  //批量获取费用表单
  initExpenseForms = () => {
    const { expenseTypeList, formInfo } = this.props.params;
    let expenseTypeOIDList = expenseTypeList.map(item => item.expenseTypeOID);
    this.setState({loading: true, expenseTypeList});
    requestService.getExpenseForms(expenseTypeOIDList, formInfo.setOfBooksId).then(res => {
      this.setState({loading: false});
      this.setState({expenseForms: res.data});
    }).catch(err => {
      errorMessage(err.response);
      this.setState({loading: false});
    });
  };

  initSuppliers = () => {
    Promise.all([
      travelService.travelSuppliers(2001),
      travelService.travelSuppliers(2002),
      travelService.travelSuppliers(2003)
    ]).then(res => {
      this.setState({
        suppliers: {
          '2001': res[0].data['2001'] || [],
          '2002': res[1].data['2002'] || [],
          '2003': res[2].data['2003'] || []
        }
      })
    }).catch(e => {
      errorMessage(e.response);
    });
  };

  //获取币种
  initCurrencyOptions = () => {
    const { jobInfo, info, formInfo } = this.props.params;
    baseService.getAllCurrencyByLanguage(
      'zh_cn',
      info.applicantOID,
      null,
      true,
      formInfo.fromType === 3 ? undefined : jobInfo.id,
      formInfo.fromType === 3 ? info.setOfBooksId : undefined
    ).then(res => {
      let currencyOptions = [];
      //过滤掉禁用的企业币种
      res.data.map(item => {
        item.enable && currencyOptions.push(item)
      });
      this.setState({currencyOptions});
    }).catch(err => {
      errorMessage(err.response);
    });
  };

  //初始化分摊相关的参数
  initApportionParams = () => {
    const { company, user, newProfile } = this.props;
    const { jobInfo, info } = this.props.params;
    let apportionParams = {
      departmentOID: requestUtil.getApportionCompanyDepartment(info.custFormValues, jobInfo, company, 'department'),
      companyOID: requestUtil.getApportionCompanyDepartment(info.custFormValues, jobInfo, company, 'company'),
      //预算明细上分摊相关的变量定义
      apportionTemplate: {
        entityType: 1001,
        scale: 0,
        amount: 0,
        defaultApportion : false,
        costCenterItems: []
      },//新增一行费用分摊的模板, 也就是非默认分摊的模板
      defaultApportion: {
        entityType: 1001,
        scale: 100,
        amount: 0,
        defaultApportion : true,
        costCenterItems: []
      },//默认分摊的模板，初始化的时候用
    };
    requestUtil.initApportionTemplate(info.custFormValues, apportionParams.apportionTemplate);
    apportionParams.defaultApportion = requestUtil.initDefaultApportion(info.custFormValues, newProfile, jobInfo);
    this.setState({apportionParams});
  };

  //获取汇率容差
  initRateDeviation = () => {
    const { company } = this.props; //申请人所在公司
    baseService.getRateDeviation(company.tenantId, company.setOfBooksId).then(res => {
      this.setState({
        warnExchangeRateTol: res.data.warnExchangeRateTol,
        prohibitExchangeRateTol: res.data.prohibitExchangeRateTol
      });
    });
  };

  onCancel = () => {
    const { isBatchSubsidy } = this.props.params;
    if (isBatchSubsidy) {
      eventTrack({
        category: '计算补贴',
        action: '弹窗-取消'
      });
    }
    this.props.close();
  };

  //删除一个费用
  //新建的时候key是前端生成的唯一标识，批量编辑差补的时候key是applicationCustomBudgetId
  handleDelete = (e, itineraryHeadId, key) => {
    eventTrack({
      category: '行程明细新建/编辑',
      action: '删除明细'
    });
    const { isBatchSubsidy } = this.props.params;
    let { itineraryHeadList } = this.state;
    if (isBatchSubsidy) {
      this.setState({loading: true});
      requestService.removeItineraryBudget(key).then(res => {
        sessionStorage.setItem('isNeedApplicationRefresh', 'true');
        itineraryHeadList && itineraryHeadList.forEach(itinerary => {
          if (itinerary.itineraryHeadId === itineraryHeadId) {
            let spliceIndex = -1;
            itinerary.itineraryBudgetDTOList && itinerary.itineraryBudgetDTOList.forEach((expense, expenseIndex) => {
              if (expense.applicationCustomBudgetId === key) {
                spliceIndex = expenseIndex;
              }
            });
            if (spliceIndex > -1) {
              itinerary.itineraryBudgetDTOList.splice(spliceIndex, 1);
              delete this.formRefObj[`${key}`];
            }
          }
        });
        this.setState({itineraryHeadList, loading: false});
      }).catch(err => {
        this.setState({loading: false});
        errorMessage(err.response);
      });
    } else {
      itineraryHeadList && itineraryHeadList.forEach(itinerary => {
        if (itinerary.itineraryHeadId === itineraryHeadId) {
          let spliceIndex = -1;
          itinerary.quickExpenseList && itinerary.quickExpenseList.forEach((expense, expenseIndex) => {
            if (expense.frontOID === key) {
              spliceIndex = expenseIndex;
            }
          });
          if (spliceIndex > -1) {
            itinerary.quickExpenseList.splice(spliceIndex, 1);
            delete this.formRefObj[`${key}`];
            itinerary.quickExpenseOIDList = itinerary.quickExpenseList.filter(item => item.expenseTypeOID);
          }
        }
      });
      this.setState({itineraryHeadList});
    }
  };

  handleSave = () => {
    const { itineraryHeadList, expenseForms } = this.state;
    const { info, isEditBudget, budgetId, isBatchSubsidy } = this.props.params;
    const { close } = this.props;
    if (isBatchSubsidy) {
      eventTrack({
        category: '计算补贴',
        action: '弹窗-确定'
      });
    }
    let applicationOID = info.applicationOID;
    let itineraryBudgetList = [];
    let headLength = itineraryHeadList.length;
    let i = 0;
    for (i; i < headLength; i++) {
      let expenseLength = itineraryHeadList[i].quickExpenseList.length || 0;
      if (isBatchSubsidy) {
        expenseLength = itineraryHeadList[i].itineraryBudgetDTOList.length || 0;
      }
      let j = 0;
      for (j; j < expenseLength; j++) {
        let expense = itineraryHeadList[i].quickExpenseList[j];
        if (isBatchSubsidy) {
          expense = itineraryHeadList[i].itineraryBudgetDTOList[j];
        }
        let refKey = `${isBatchSubsidy ? expense.applicationCustomBudgetId : expense.frontOID}`;
        let res = this.formRefObj[refKey].validateItemsValue();
        if (!res.validateResult) {
          //校验不通过
          return;
        } else {
          let budgetRow = {
            itineraryHeadId: itineraryHeadList[i].itineraryHeadId,
            expenseTypeOID: expense.expenseTypeOID,
            budgetFormOID: requestUtil.getBudgetFormOID(expense.expenseTypeOID, expenseForms),
            applicationCustomBudgetId: isBatchSubsidy ? expense.applicationCustomBudgetId : (isEditBudget ? budgetId : undefined),
            applicationOID,
            ...res
          };
          itineraryBudgetList.push(budgetRow);
        }
      }
    }

    if (!itineraryBudgetList.length) {
      if (isBatchSubsidy) {
        close(true);
        return;
      }
      message.error(messages('request-1.key382')/*请添加行程明细*/);
      return;
    }

    this.setState({savingLoading: true});
    if (isBatchSubsidy) {
      requestService.batchSaveItineraryBudget(itineraryBudgetList).then(res => {
        if (close) {
          close(true);
        }
      }).catch(err => {
        errorMessage(err.response);
        this.setState({savingLoading: false});
      });
    } else {
      if (isEditBudget) {
        requestService.saveItineraryBudget(itineraryBudgetList[0]).then(res => {
          if (close) {
            close(true);
          }
        }).catch(err => {
          errorMessage(err.response);
          this.setState({savingLoading: false});
        });
      } else {
        requestService.addItineraryBudget(applicationOID, itineraryBudgetList).then(res => {
          if (close) {
            close(true);
          }
        }).catch(err => {
          errorMessage(err.response);
          this.setState({savingLoading: false});
        });
      }
    }
  };

  /**
   * 控制添加费用类型弹框
   * @param isOpen 弹框的展示
   * @param isAddBudget 确定btn的回调，是否要打开添加费用控件，分摊界面
   * @param itinerary 在哪个行程头下添加明细
   */
  showExpenseModal = (isOpen, isAddBudget, itinerary) => {
    let { selectedExpense, expenseTypeList, expenseForms, itineraryHeadList, expenseItinerary } = this.state;
    const { formInfo } = this.props.params;
    if (isOpen) {
      eventTrack({
        category: '行程明细新建/编辑',
        action: '添加行程明细'
      });
    }
    if (isOpen && itinerary && itinerary.quickExpenseList && itinerary.quickExpenseList.length === 10) {
      message.error(messages('request-1.key383')/*每个行程下最多连续添加10个明细*/);
      return;
    }
    if (isOpen) {
      this.setState({selectedExpense: {}, expenseItinerary: itinerary || {}});
    }
    if (!isOpen && isAddBudget) {
      //点击确定添加一个明细
      this.setState({modalLoading: true});
      requestService.getExpenseForms([selectedExpense.expenseTypeOID], formInfo.setOfBooksId).then(res => {
        let expenseForm = res.data && res.data[0];
        if (expenseForms.filter(item => item.formOID).indexOf(expenseForm.formOID) === -1) {
          expenseForms.push(expenseForm);
          expenseTypeList.push(selectedExpense);
        }
        itineraryHeadList.forEach(itineraryItem => {
          if (itineraryItem.itineraryHeadId === expenseItinerary.itineraryHeadId) {
            itineraryItem.quickExpenseList.push({
              expenseTypeOID: selectedExpense.expenseTypeOID,
              frontOID: travelUtil.generateUid()
            });
            itineraryItem.quickExpenseOIDList = itineraryItem.quickExpenseList.filter(item => item.expenseTypeOID);
          }
        });
        this.setState({
          expenseForms,
          expenseTypeList,
          itineraryHeadList,
          modalLoading: false,
          modalVisible: false
        });
      }).catch(err => {
        errorMessage(err.response);
        this.setState({modalLoading: false});
      });
    } else {
      this.setState({modalVisible: isOpen});
    }
  };

  getExpenseParams = () =>{
    const { formInfo, jobInfo, info } = this.props.params;
    const { user } = this.props;
    if (formInfo && formInfo.formOID) {
      let companyOID = travelUtil.getFormHeadValue(info.custFormValues, 'select_company') || jobInfo.companyOID || user.companyOID;
      return {
        companyOID,
        formOID: formInfo.formOID,
        subsidyType: 0,
        userOID: user.userOID,
        setOfBooksId: info.setOfBooksId || formInfo.setOfBooksId
      };
    } else {
      return {};
    }
  };

  handleSelectExpenseType = (value) => {
    this.setState({selectedExpense: value});
  };

  /**
   * 差补明细修改过后要更新差补相关数据，以及刷新币种和金额
   * @param subsidyInfo
   * @param formRefKey
   * @param applicationCustomBudgetId 当前操作的是那个差补明细，所有差补明细被清空了，这个id也会有值
   */
  handleRefreshSubsidy = (subsidyInfo, formRefKey, applicationCustomBudgetId) => {
    let { itineraryHeadList } = this.state;
    itineraryHeadList && itineraryHeadList.forEach(itinerary => {
      let spliceIndex = -1;
      itinerary.itineraryBudgetDTOList && itinerary.itineraryBudgetDTOList.forEach((budget, budgetIndex) => {
        if (budget.applicationCustomBudgetId === applicationCustomBudgetId) {
          if (subsidyInfo) {
            budget.travelSubsidiesRequestItemDetailDTOs = subsidyInfo.travelSubsidiesRequestItemDetailDTOs;
            budget.amount = subsidyInfo.amount;
            budget.currencyCode = subsidyInfo.currencyCode;
          } else {
            //差补明细被清空，后台已把该条行程明细清空
            spliceIndex = budgetIndex;
          }
        }
      });
      if (spliceIndex > -1) {
        itinerary.itineraryBudgetDTOList.splice(spliceIndex, 1);
        delete this.formRefObj[formRefKey];
      }
    });
    this.setState({itineraryHeadList});
    //更新对应差补费用下的币种，金额，以及如果有分摊要刷新分摊
    if (this.formRefObj[formRefKey]) {
      this.formRefObj[formRefKey].setAmountAndCurrency(subsidyInfo.amount, subsidyInfo.currencyCode);
    }
    if (Object.keys(this.formRefObj).length === 0) {
      this.props.close();
    }
  };

  render() {
    const { loading, savingLoading, expenseForms, suppliers, currencyOptions, apportionParams, itineraryHeadList,
      modalVisible, selectedExpense, expenseTypeList, modalLoading, prohibitExchangeRateTol, warnExchangeRateTol } = this.state;
    const { isEditBudget, budgetId, isBatchSubsidy, isQuickPlan } = this.props.params;
    return (
      <div className="itinerary-budget new-form">
        <Spin spinning={loading}>
          <div style={{paddingLeft: 40}}>
            {itineraryHeadList && itineraryHeadList.map((itinerary, itineraryIndex) => {
              let dataList = itinerary.quickExpenseList || [];
              if (isBatchSubsidy) {
                dataList = itinerary.itineraryBudgetDTOList || [];
              }
              return (
                <div key={itinerary.itineraryHeadId} style={isBatchSubsidy && itineraryIndex + 1 !== itineraryHeadList.length ? {marginBottom: 32} : {}}>
                  <If value={isBatchSubsidy || (!isBatchSubsidy && !isEditBudget)}>
                    <div className="itinerary-item-title">
                      <If value={!!isQuickPlan}>
                        <div className="font-no">{messages('request-1.key290')/*行程*/}{itineraryIndex + 1}</div>
                      </If>
                      <div>
                        <span className="font-title">{itinerary.fromCityName}&nbsp;-&nbsp;{itinerary.toCityName}</span>
                        <span className="font-sub">
                          {moment(itinerary.startDate).format('YYYY-MM-DD')}
                          &nbsp;~&nbsp;
                          {moment(itinerary.endDate).format('YYYY-MM-DD')}，
                          {messages('request-1.key384',{arg1: travelUtil.calculateDate(itinerary.startDate,itinerary.endDate)})/*共{arg1}天*/}
                        </span>
                      </div>
                    </div>
                  </If>
                  {dataList.map((expense, expenseIndex) => {
                    let quickExpense = requestUtil.getQuickExpense(expense.expenseTypeOID, expenseTypeList);
                    let customFormFields = [];
                    let subsidyInfo = {};
                    if (isEditBudget) {
                      customFormFields = requestUtil.getFormValues(itinerary, expense.expenseTypeOID, isBatchSubsidy ? expense.applicationCustomBudgetId : budgetId);
                      subsidyInfo = requestUtil.getSubsidyInfo(itinerary, isBatchSubsidy ? expense.applicationCustomBudgetId : budgetId);
                    } else {
                      customFormFields = requestUtil.getFormFields(itinerary.itineraryHeadId, expense.expenseTypeOID, expenseForms);
                    }
                    return (
                      <div key={isBatchSubsidy ? expense.applicationCustomBudgetId : expense.frontOID} style={{position: 'relative'}}>
                        <img src={quickExpense.iconURL} className="icon-img"/>
                        <Row type="flex" align="middle" style={{marginBottom: 12}}>
                          <Col span={20} className="expense-title">{messages('request-1.key385',{arg1: quickExpense.name})/*添加{arg1}*/}</Col>
                          <If value={isBatchSubsidy || (!isBatchSubsidy && !isEditBudget)}>
                            <Col span={4} style={{textAlign: 'right'}}>
                              <span className="icon-btn">
                                <Popconfirm
                                  placement="topRight"
                                  onConfirm={(e) => this.handleDelete(e, itinerary.itineraryHeadId, isBatchSubsidy ? expense.applicationCustomBudgetId : expense.frontOID)}
                                  title={messages('request-1.key386')/*你确认要删除？*/}
                                >
                                  <a onClick={(e) => {e.preventDefault();e.stopPropagation();}}><Icon type="delete" />&nbsp;{messages('common.delete')/*删除*/}</a>
                                </Popconfirm>
                              </span>
                            </Col>
                          </If>
                        </Row>
                        <If value={requestUtil.isSubsidy(itinerary, isBatchSubsidy ? expense.applicationCustomBudgetId : budgetId) && subsidyInfo.applicationCustomBudgetId}>
                          <SubsidyDetail
                            subsidyInfo={subsidyInfo}
                            params={{
                              ...this.props.params,
                              prohibitExchangeRateTol,
                              warnExchangeRateTol,
                              formRefKey: isBatchSubsidy ? expense.applicationCustomBudgetId : expense.frontOID
                            }}
                            refreshSubsidy={this.handleRefreshSubsidy}
                          />
                        </If>
                        <If value={customFormFields.length}>
                          <ItineraryForm
                            customFormFields={customFormFields}
                            params={{
                              ...this.props.params,
                              suppliers,
                              itinerary,
                              currencyOptions,
                              apportionParams,
                              expenseTypeName: quickExpense.name,
                              expenseTypeOID: expense.expenseTypeOID,
                              budgetId: budgetId || expense.applicationCustomBudgetId
                            }}
                            wrappedComponentRef={(form) => this.formRefObj[`${isBatchSubsidy ? expense.applicationCustomBudgetId : expense.frontOID}`] = form}
                          />
                        </If>
                        <If value={(isBatchSubsidy && expenseIndex + 1 !== dataList.length) || (!isBatchSubsidy && !isEditBudget)}>
                          <Divider style={{marginTop: 30, marginBottom: 20}}/>
                        </If>
                      </div>
                    )
                  })}
                  <If value={!isEditBudget && !isBatchSubsidy}>
                    <div className="ant-form-item-control-wrapper" style={{marginLeft: 152, marginBottom: 20}}>
                      <Button className="new-expense-btn" type="dashed" icon="plus" onClick={() => this.showExpenseModal(true, false, itinerary)}>
                        {messages('request-1.key387')/*添加行程明细*/}
                      </Button>
                    </div>
                  </If>
                </div>
              )
            })}
          </div>
        </Spin>
        <div className="slide-footer">
          <Button type="primary" onClick={this.handleSave} loading={savingLoading}>{messages('common.ok')/*确定*/}</Button>
          <Button onClick={this.onCancel}>{messages('common.cancel')/*取消*/}</Button>
        </div>
        <Modal
          title={messages('request-1.key325')/*添加费用类型及金额*/}
          wrapClassName="expense-type-modal"
          width={860}
          footer={
            <div>
              <Button onClick={() => this.showExpenseModal(false)}>{messages('common.cancel')/*取消*/}</Button>
              <Button
                type="primary"
                loading={modalLoading}
                disabled={!selectedExpense.id}
                onClick={() => this.showExpenseModal(false, true)}
              >
                {messages('common.ok')/*确定*/}
              </Button>
            </div>
          }
          visible={modalVisible}
          onCancel={() => this.showExpenseModal(false)}
        >
          <div className="expense-type-container">
            <ExpenseTypeSelector
              onSelect={this.handleSelectExpenseType}
              source="formV3"
              param={this.getExpenseParams()}
              value={selectedExpense}
            />
          </div>
        </Modal>
      </div>
    )
  }
}

RequestItineraryBudget.propTypes = {

};

function mapStateToProps(state) {
  return {
    user: state.login.user,
    company: state.login.company,
    newProfile: state.login.options
  }
}

export default connect(mapStateToProps)(RequestItineraryBudget);
